/**
 * @author nttdocomo
 */
define(function(require) {
	require('./trigger');
	aries.klass("aries.form.field.Picker", aries.form.field.Trigger.extend({
		events : {
			'keydown input' : 'onKeyDown',
			'click input' : 'onKeyDown'
		},

		/**
		 * @cfg {Boolean} matchFieldWidth
		 * Whether the picker dropdown's width should be explicitly set to match the width of the field. Defaults to true.
		 */
		matchFieldWidth : true,

		/**
		 * @cfg {String} [openCls='x-pickerfield-open']
		 * A class to be added to the field's {@link #bodyEl} element when the picker is opened.
		 */
		openCls : aries.baseCSSPrefix + 'pickerfield-open',

		/**
		 * @cfg {String} pickerAlign
		 * The {@link Ext.Element#alignTo alignment position} with which to align the picker. Defaults to "tl-bl?"
		 */
		pickerAlign : {
			"my" : "left top",
			"at" : "left bottom",
			"collision" : "none none"
		},

		/**
		 * Aligns the picker to the input element
		 * @protected
		 */
		alignPicker : function() {
			var me = this, picker = me.getPicker();

			if (me.isExpanded) {
				if (me.matchFieldWidth) {
					// Auto the height (it will be constrained by min and max width) unless there are no records to display.
					picker.setWidth(me.triggerWrap.width());
				}
				if (picker.isFloating()) {
					me.doAlign();
				}
			}
		},

		/**
		 * Collapses this field's picker dropdown.
		 */
		collapse : function() {
			if (this.isExpanded && !this.isDestroyed) {
				var me = this, openCls = me.openCls, picker = me.picker, doc = $(document), collapseIf = me.collapseIf, aboveSfx = '-above';

				// hide the picker and set isExpanded flag
				picker.hide();
				me.isExpanded = false;

				// remove the openCls
				me.bodyEl.removeClass([openCls, openCls + aboveSfx].join(" "));
				picker.$el.removeClass(picker.baseCls + aboveSfx);

				// remove event listeners
				doc.off('mousewheel', collapseIf, me);
				doc.off('mousedown', collapseIf, me);
				//Ext.EventManager.removeResizeListener(me.alignPicker, me);
				me.trigger('collapse', me);
				me.onCollapse();
			}
		},

		/**
		 * @private
		 * Runs on mousewheel and mousedown of doc to check to see if we should collapse the picker
		 */
		collapseIf : function(e) {
			var me = this;

			if (!me.isDestroyed && !me.bodyEl.find(e.target).length && !me.picker.$el.find(e.target).length && !me.isEventWithinPickerLoadMask(e)) {
				me.collapse();
			}
		},

		/**
		 * Performs the alignment on the picker using the class defaults
		 * @private
		 */
		doAlign : function() {
			var me = this, picker = me.picker, aboveSfx = '-above', isAbove;

			me.picker.alignTo(me.inputEl, me.pickerAlign, me.pickerOffset);
			// add the {openCls}-above class if the picker was aligned above
			// the field due to hitting the bottom of the viewport
			isAbove = picker.$el.position().top/*getY()*/ < me.inputEl.position().top/*getY()*/;
			me.bodyEl[isAbove ? 'addClass' : 'removeClass'](me.openCls + aboveSfx);
			picker[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
		},

		/**
		 * Expands this field's picker dropdown.
		 */
		expand : function() {
			var me = this, bodyEl, picker, collapseIf;

			if (me.rendered && !me.isExpanded && !me.isDestroyed) {
				bodyEl = me.bodyEl;
				picker = me.getPicker();
				collapseIf = me.collapseIf;

				// show the picker and set isExpanded flag
				picker.show();
				me.isExpanded = true;
				me.alignPicker();
				bodyEl.addClass(me.openCls);

				// monitor clicking and mousewheel
				$(document).bind({
					"mousewheel" : _.bind(collapseIf, me),
					"mousedown" : _.bind(collapseIf, me)
				})
				/*me.mon(Ext.getDoc(), {
				 mousewheel : collapseIf,
				 mousedown : collapseIf,
				 scope : me
				 });
				 Ext.EventManager.onWindowResize(me.alignPicker, me);
				 me.trigger('expand', me);*/
				me.onExpand();
			}
		},

		/**
		 * Returns a reference to the picker component for this field, creating it if necessary by
		 * calling {@link #createPicker}.
		 * @return {Ext.Component} The picker component
		 */
		getPicker : function() {
			var me = this;
			return me.picker || (me.picker = me.createPicker());
		},
		initComponent : function() {
			aries.form.field.Trigger.prototype.initComponent.apply(this, arguments);
		},

		initEvents : function() {
			/*var me = this;
			 aries.form.field.Trigger.prototype.initEvents.apply(this,arguments);

			 // Add handlers for keys to expand/collapse the picker
			 me.keyNav = new Ext.util.KeyNav(me.inputEl, {
			 down : me.onDownArrow,
			 esc : {
			 handler : me.onEsc,
			 scope : me,
			 defaultEventAction : false
			 },
			 scope : me,
			 forceKeyDown : true
			 });

			 // Non-editable allows opening the picker by clicking the field
			 if (!me.editable) {
			 me.mon(me.inputEl, 'click', me.onTriggerClick, me);
			 }

			 // Disable native browser autocomplete
			 if (Ext.isGecko) {
			 me.inputEl.dom.setAttribute('autocomplete', 'off');
			 }*/
		},

		/**
		 * returns true if the picker has a load mask and the passed event is within the load mask
		 * @private
		 * @param {Ext.EventObject} e
		 * @return {Boolean}
		 */
		isEventWithinPickerLoadMask : function(e) {
			var loadMask = this.picker.loadMask;

			return loadMask ? e.within(loadMask.maskEl, false, true) || e.within(loadMask.el, false, true) : false;
		},

		mimicBlur : function(e) {
			var me = this, picker = me.picker;
			// ignore mousedown events within the picker element
			if (!picker || !$(e.target).closest(picker.el).length && !me.isEventWithinPickerLoadMask(e)) {
				aries.form.field.Trigger.prototype.mimicBlur.apply(this, arguments);
			}
		},
		onKeyDown : function(e) {
			switch(e.keyCode) {
				case 40:
					this.onDownArrow()
					break

			}
		},

		onDownArrow : function(e) {
			if (!this.isExpanded) {
				// Don't call expand() directly as there may be additional processing involved before
				// expanding, e.g. in the case of a ComboBox query.
				this.onTriggerClick();
			}
		},

		/**
		 * Handles the trigger click; by default toggles between expanding and collapsing the picker component.
		 * @protected
		 */
		onTriggerClick : function() {
			var me = this;
			if (!me.readOnly && !me.disabled) {
				if (me.isExpanded) {
					me.collapse();
				} else {
					me.expand();
				}
				me.inputEl.focus();
			}
		}
	}))
})
